import AMapLoader from '@amap/amap-jsapi-loader';
import type { Map, Marker, AMapNamespace, GeocodeResult, LngLat } from '@amap/amap-jsapi-loader';

interface CitySearchResult {
  info: string;
  infocode: string;
  city: string;
  adcode: string;
  district: string;
  province: string;
  position: LngLat;
  // position: [number, number];
  [key: string]: any;
}

interface SearchResult {
  poiList: {
    pois: Array<any>;
  };
  [key: string]: any;
}

export default class GdMapUtil {
  private static map: Map | null = null;

  static initAMap(): Promise<AMapNamespace> {
    
    return AMapLoader.load({
      key: "d3b52a7f835f060a70ab66645d3d6428",
      version: "2.0",
      plugins: ['AMap.CitySearch', 'AMap.Geolocation', 'AMap.Geocoder'],
    });
  }

  static getCity(): Promise<CitySearchResult> {
    return new Promise((resolve, reject) => {
      this.initAMap()
        .then((AMap) => {
          AMap.plugin('AMap.CitySearch', () => {
            const citySearch = new AMap.CitySearch()
  
            citySearch.getLocalCity((status: string, result: any) => {
              console.log('Get local city status:', status);
              console.log('Get local city result:', JSON.stringify(result, null, 2));
            
              if (status === 'complete') {
                console.log('Location acquired:', result);
                resolve(result);
              } else {
                console.error('Geolocation failed with status:', status, 'result:', result);
                reject(new Error('get location error'));
              }
            });
          });
        })
        .catch((error) => {
          console.error('Failed to initialize AMap or load plugin:', error);
          reject(error);
        });
    });
  }

  static getLocationCity(): Promise<CitySearchResult> {
    return new Promise((resolve, reject) => {
      this.initAMap()
        .then((AMap) => {
          AMap.plugin('AMap.Geolocation', () => {
            const geolocation = new AMap.Geolocation({
              enableHighAccuracy: true,
              timeout: 10000,
              position: "RB",
              zoomToAccuracy: true,
            });

            geolocation.getCurrentPosition((status: string, result: any) => {
              if (status === 'complete') {
                resolve(result);
              } else {
                console.error('Geolocation failed:', status, result); // 更详细的错误信息
                reject(new Error('get location error'));
              }
            });
          });
        })
        .catch((error) => {
          console.error('Failed to initialize AMap or load plugin:', error);
          reject(error);
        });
    });
  }

  static getSearchOptions(query: string): Promise<any> {
    return new Promise((resolve, reject) => {
      this.initAMap()
        .then((AMap) => {
          AMap.plugin(["AMap.AutoComplete"], () => {
            const autocomplete = new AMap.AutoComplete();
            autocomplete.search(query, (status: string, result: any) => {
              if (status === "complete") {
                resolve(result);
              } else {
                reject(new Error("get search error"));
              }
            });
          });
        })
        .catch((error) => reject(error));
    });
  }

  static setMarker(lng: number, lat: number): Promise<Marker> {
    return new Promise((resolve, reject) => {
      this.initAMap()
        .then((AMap) => {
          AMap.plugin(["AMap.Marker"], () => {
            const marker = new AMap.Marker({
              position: new AMap.LngLat(lng, lat),
            });
            resolve(marker);
          });
        })
        .catch((error) => reject(error));
    });
  }

  static getPlaceSearch(keyword: string): Promise<SearchResult> {
    return new Promise((resolve, reject) => {
      this.initAMap()
        .then((AMap) => {
          AMap.plugin(["AMap.PlaceSearch"], () => {
            const placeSearch = new AMap.PlaceSearch();
            placeSearch.search(keyword, (status: string, result: SearchResult) => {
              if (status === "complete") {
                resolve(result);
              } else {
                reject(new Error("get place search error"));
              }
            });
          });
        })
        .catch((error) => reject(error));
    });
  }
  
  static GeocoderGetAddress(lng: number, lat: number): Promise<GeocodeResult> {
    return new Promise((resolve, reject) => {
      this.initAMap()
        .then((AMap) => {
          AMap.plugin(['AMap.Geocoder'], () => {
            const geocoder = new AMap.Geocoder({});
            geocoder.getAddress([lng, lat], (status: string, result: GeocodeResult) => {
              if (status === 'complete' && result.info === 'OK') {
                resolve(result);
              } else {
                reject(new Error('get geocoder address error'));
              }
            });
          });
        })
        .catch(error => reject(error));
    });
  }
  
  static destroyMap(): void {
    if (this.map) {
      this.map.destroy();
      this.map = null;
    }
  }
}